import game
import lepton
import lepton.renderer
import lepton.emitter
import lepton.controller
import map
import math
from pyglet.gl import *
import sprite
import thing
import vector


class Building(thing.Thing):

	group = sprite.Group()

	def __init__(self, id, owner, health, location, size):
		thing.Thing.__init__(self, id, owner, health, location, size, None)
		game.state.push_handlers(self)
		self.start_size = self.built_size * 0.01
		self.size = size is None and self.start_size or size # default

		self.rally = vector.Vec3(*self.location)
		self.rally.x += (self.built_size / 2.0) + 0.1
		self.rally.y -= (self.built_size / 2.0) - 0.1

		self.vertex_list = pyglet.graphics.vertex_list(24, 'v3f', 'c3f',
			('n3f/static', (
				# bottom
				0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1,
				# front
				0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0,
				# right
				1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,
				# back
				0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0,
				# left
				-1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0,
				# top
				0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1,
			)))
		# ???: If a building is destroyed do we need to delete the vertex list?
		self.dust = lepton.ParticleGroup(
			controllers=[
				lepton.emitter.StaticEmitter(
					time_to_live=self.build_time,
					rate=15,
					template=lepton.Particle(
						# ick, there must be a better way...
						position=tuple(game.state.tactical_handler.map_view.opengl_coordinates(self.location)),
						size=(.6 * self.built_size, .6 * self.built_size, 0),
						color=(.8, .8, .8)),
					deviation=lepton.Particle(
						position=(.4 * self.built_size, .4 * self.built_size, .4 * self.built_size),
						size=(.2 * self.built_size, .2 * self.built_size, 0),
						velocity=(.01 * self.built_size, .01 * self.built_size, .01 * self.built_size),
						rotation=(0, 0, math.pi * .1))),
				lepton.controller.Lifetime(.3 * self.build_time),
				lepton.controller.Movement(),
				lepton.controller.Fader(
					fade_in_end=(.05 * self.build_time),
					max_alpha=.1,
					fade_out_start=(.1 * self.build_time),
					fade_out_end=(.3 * self.build_time))],
			renderer=lepton.renderer.BillboardRenderer())

	def update_vertices(self):
		x, y, z = game.state.tactical_handler.map_view.opengl_coordinates(self.location)
		hs = 0.5 * self.size
		self.vertex_list.vertices = (
			# bottom
			x - hs, y - hs, z,
			x + hs, y - hs, z,
			x + hs, y + hs, z,
			x - hs, y + hs, z,
			# front
			x - hs, y - hs, z,
			x + hs, y - hs, z,
			x + hs, y - hs, z + hs,
			x - hs, y - hs, z + hs,
			# right
			x + hs, y - hs, z,
			x + hs, y + hs, z,
			x + hs, y + hs, z + hs,
			x + hs, y - hs, z + hs,
			# back
			x - hs, y + hs, z,
			x + hs, y + hs, z,
			x + hs, y + hs, z + hs,
			x - hs, y + hs, z + hs,
			# left
			x - hs, y - hs, z,
			x - hs, y + hs, z,
			x - hs, y + hs, z + hs,
			x - hs, y - hs, z + hs,
			# top
			x - hs, y - hs, z + hs,
			x + hs, y - hs, z + hs,
			x + hs, y + hs, z + hs,
			x - hs, y + hs, z + hs,
			)

	def on_draw_tactical_iso(self):
		self.update_vertices()
		self.update_color()
		self.vertex_list.draw(GL_QUADS)

		glDisable(GL_DEPTH_TEST)
		tex = pyglet.resource.texture('puff.png')
		glEnable(tex.target)
		glTexParameteri(tex.target, GL_TEXTURE_WRAP_S, GL_CLAMP)
		glTexParameteri(tex.target, GL_TEXTURE_WRAP_T, GL_CLAMP)
		glTexParameteri(tex.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
		glTexParameteri(tex.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
		self.dust.draw()
		glDisable(tex.target)
		glEnable(GL_DEPTH_TEST)

		thing.Thing.draw(self)

	def on_update(self, dt):
		# grow while building
		if self.size < self.built_size:
			self.size += dt * (self.built_size - self.start_size) / self.build_time
			if self.size > self.built_size:
				self.size = self.built_size

		self.dust.update(dt)

		thing.Thing.on_update(self, dt)

	def on_building_state_update(self, building_id, owner, health, location, size, target):
		if self.id == building_id:
			thing.Thing.on_thing_state_update(self, owner, health, location, size, target)

	def on_building_kill(self, building_id):
		if self.id == building_id:
			game.state.remove_handlers(self)
			self.kill()


class Sanctuary(Building):

	mineral_cost = 400
	gas_cost = 0
	built_size = 0.9
	build_time = 45 # seconds
	health = 1500
	color = (0.0, 0.0, 0.5)
	weapons = []


class Hive(Building):

	mineral_cost = 300
	gas_cost = 0
	built_size = 0.8
	build_time = 30 # seconds
	health = 1250
	color = (0.5, 0.0, 0.0)
	weapons = []


class Citadel(Building):

	mineral_cost = 400
	gas_cost = 0
	built_size = 1
	build_time = 60 # seconds
	health = 1500
	color = (0.5, 0.5, 0.0)
	weapons = []

